4장 변수
4-1. 변수란 무엇인가? 왜 필요한가?
아래 자바스크립트 코드를 실행하다고 생각해보자.
10 + 20;- 사람이 계산하는 방법
- 10, 20, +의 의미를 해석할 수 있어야 한다.
- 10, 20을 먼저 두뇌에 기억한다.
- 10과 20을 더한 결과인 30을 두뇌에 기억한다.
- 컴퓨터가 계산하는 방법 : cpu가 연산하고, memory가 기억한다.
- 10과 20을 메모리에서 기억한다
⇒ 메모리란?
데이터를 저장할 수 있는 메모리 셀의 집합체
- 메모리 셀 한개의 크기 : 1byte(8bit) ⇒ 컴퓨터는 모든 데이터를 2진수 형태로 저장한다.
- 메모리 셀마다 고유의 주소가 존재 ⇒ 컴퓨터는 메모리 셀 단위로 데이터를 저장(write) 하거나 읽는다(read).
- cpu에서 10과 20을 더하는 연산을 수행한다.
- 연산한 결과인 30을 메모리에서 기억한다.
또다른 메모리 셀에 30이 저장된다
- 10과 20을 메모리에서 기억한다
⇒ 메모리란?
데이터를 저장할 수 있는 메모리 셀의 집합체
그런데, JS에서는 연산 결과인 30을 재사용하기 위해 메모리 셀에 직접 접근할 수 없다.
포인터를 사용하는 C, C++ 등과 다르게 JS는 메모리 주소를 통해 값에 직접 접근하는 것을 허용하지 X
왜냐면, 동일한 컴퓨터에서 동일한 코드를 실행하더라도 값이 저장되는 메모리 주소는 매번 변경되기 때문이다.
⇒ 그래서, 값에 접근하기 위해서는 변수를 이용해서 값에 접근해야 한다.
4-1-1. 변수란?
하나의 값을 저장하기 위해 확보한 메모리 공간, 또는 그 메모리 공간을 식별하기 위해 붙인 이름
→ 즉, 값의 위치의 식별자이다!
변수를 활용하여 코드를 다시 작성해보자.
var result = 10 + 20;- 변수명 : 변수 이름
ex)
result - 변수값 : 변수에 저장된 값 ex) 30
- 변수 할당 : write
ex)
result에 30을 저장 - 변수 참조 : read
ex)
result에 저장된 30이라는 값을 읽음

4-2. 식별자
변수 이름, 어떤 값이 저장된 메모리 주소에 붙인 이름
⇒ 즉, 식별자는 변수의 값이 아닌 메모리 주소를 기억

값은 구별하지 못 하고 메모리 주소를 구별한다.
식별자라는 용어는 변수에 국한되지 않고, 함수, 클래스 등 멤모리 상에 존재하는 값에 대한 이름은 모두 식별자
⇒ 네이밍 규칙을 준수해야 하고, 선언에 의해 JS 엔진이 식별자의 존재를 알 수 있다!
4-3. 변수 선언
변수를 생성하는 것
→ 값을 저장하기 위한 메모리 공간 확보 + 변수 이름과 확보된 메모리 공간의 주소를 연결
4-3-1. 변수 선언 키워드 종류
var, let, const
(let, const는 ES6에 추가된 키워드로, 뒤에서 더 자세히 살펴보자)
var로 변수 선언하기
-
선언 단계 : 변수 이름을 등록 → 메모리 공간 확보
var score; -
초기화 단계 : JS는 암묵적으로 undefined라는 값이 할당되어 초기화된다.

var 키워드는 선언 단계와 초기화 단계가 동시에 진행된다.
→ 쓰레기 값이 저장되는 에러로부터 안전하다.
4-3-2. 선언되지 않은 변수에 접근했을 때?
ReferenceError(참조 에러) 발생한다.
→ 해당 이름으로 등록된 변수를 찾지 못 했다는 의미
4-4. 변수 선언의 실행 시점과 변수 호이스팅
변수 호이스팅이란?
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 JS 고유의 특징
ex 1) 변수 선언문보다 변수를 참조하는 코드가 앞에 있다.
console.log(score);
var score;선언하기 전에 접근한다면 에러가 발생하지 않을까?
→ 하지만, ReferenceError가 발생하지 않고, undefined가 출력된다.
⇒ JS엔진은 변수 선언이 소스코드에 어디에 있든 다른 코드보다 먼저 실행한다.
ex 2) 변수 선언 앞뒤로 참조하는 코드
console.log(x); // x가 선언된 상태라 undefined가 출력된다
var x = 100;
console.log(x); //100이 출력된다위의 코드는 아래와 같이 JS엔진에 의해 처리된다
var x; //변수 호이스팅, 위로 끌어올려짐
console.log(x); // undefined
var x = 100;
console.log(x); // 100var 키워드로 변수를 선언했기에, 선언 단계와 초기화가 동시에 실행된다.
→ undefined 값을 확인할 수 있음
4-4-1. 그럼 만약 let, const 등으로 선언했다면?
let과 const는 블록 스코프를 가지며, 블록 내에서만 접근 가능하다
⇒ 변수 선언이 끌어올려지지만, 선언 전에는 접근할 수 없다.
선언 전에 접근을 시도하면 오류가 난다
console.log(b); // ReferenceError: b is not defined
let b = 20;
console.log(c); // ReferenceError: c is not defined
const c = 30;왜냐하면 let과 const는 선언이 호이스팅되지만 초기화는 호이스팅되지 않는다.
4-5. 값의 할당
그렇다면 undefined로 초기화되었던 변수에 어떻게 값을 할당하는가?
⇒ 할당연산자 =을 사용하여, 오른쪽에 있는 값을 왼쪽으로 할당한다.
var score = 80l위에서도 언급했듯이,
선언 단계는 호이스팅으로 인해 먼저 이루어지고,
할당 단계는 순차적으로 실행되는 런타임에 실행된다.
console.log(score); // undefined -> 변수 선언은 호이스팅됨
var score; // 1
score = 80; // 2
console.log(score); // 80 -> 런타임 내에 80으로 score의 값이 할당됨그렇다면 아래 코드는 어떻게 실행될까?
console.log(score); // undefined -> 변수 선언은 호이스팅됨
score = 80; // 2
var score; // 1
console.log(score); // ??
당연히, 해당 결과도 80으로 출력된다.
4-6. 값의 재할당
4-6-1. 값의 재할당
현재 저장된 값을 버리고 새로운 값을 저장하는 것을 뜻한다.
let, var로 선언된 변수 : 값을 재할당할 수 있다.const로 선언된 변수 : 값을 재할당할 수 없다. → 한 번만 할당할 수 있다
4-6-2. 재할당 과정

값의 재할당 : score라는 변수의 메모리 주소가 새로운 주소로 바뀌는 것을 뜻한다
→ 사용하지 않는 이전 값이 메모리 주소는 가비지 콜렉터에 의해 자동해제 된다.
→ 다만, 메모리에서 언제 해제되는지 그 시점을 예측할 수는 없다!! (더더욱 개발자가 메모리 주소에 접근하면 X)
4-7. 식별자 네이밍 규칙
변수의 이름을 정하는 것은 아주아주 중요한 일이다.
→ 따라서, 어떻게 이름을 지어야 하는 지에 대한 네이밍 규칙을 준수해야 한다.
- 문자, 숫자, 언더스코어(
_), 달러기호$만 포함할 수 있다. - 숫자로 시작할 수는 없다.
- 예약어는 식별자로 사용할 수 없다.
4-7-1. 네이밍 컨벤션
대표적으로 4가지 유형의 네이밍 컨벤션이 있다
- 카멜 케이스 : 변수, 함수의 이름
let devoceanYoung;소문자대문자 - 파스칼 케이스 : 생성자 함수, 클래스 이름
let DevoceanYoung;대문자대문자 - 스네이크 케이스
let devocean_young;소문자_소문자 - 헝가리언 케이스
let strDevoceanYoung;타입대문자대문자